// zipPlugin.js
const JSZip = require('jszip');
const path = require('path');
const RawSource = require('webpack-sources').RawSource;
const zip = new JSZip();

module.exports = class ZipPlugin {
  constructor(options) {
    this.options = options;
  }

  apply(compiler) {
    // 在 emit 事件发生时，代表源文件的转换和组装已经完成，在这里可以读取到最终将输出的资源、代码块、模块及其依赖，并且可以修改输出资源的内容。 插件代码如下
    compiler.hooks.emit.tapAsync('ZipPlugin', (compilation, callback) => {
      // 创建目录名称
      const folder = zip.folder(this.options.filename);

      // 资源格式
      // compilation.assets[fileName] = {
      //   // 返回文件内容
      //   source: () => {
      //     // fileContent 既可以是代表文本文件的字符串，也可以是代表二进制文件的 Buffer
      //     return fileContent;
      //     },
      //   // 返回文件大小
      //     size: () => {
      //     return Buffer.byteLength(fileContent, 'utf8');
      //   }
      // };
      // 遍历compilation.assets对象
      for (let filename in compilation.assets) {
        // 获取source
        const source = compilation.assets[filename].source();
        // 将source添加到folder中
        folder.file(filename, source);
      }

      // 将内容生成zip
      zip
        .generateAsync({
          type: 'nodebuffer',
        })
        .then((content) => {
          // 获取output（绝对路径）
          const outputPath = path.join(
            compilation.options.output.path,
            this.options.filename + '.zip'
          );

          const outputRelativePath = path.relative(
            compilation.options.output.path,
            outputPath
          );

          // 将内容挂载到compilation.assets上，并将buffer转换为source
          compilation.assets[outputRelativePath] = new RawSource(content);
          callback();
        });
    });
  }
};
